﻿using MsBox.Avalonia.Enums;
using OfficeOpenXml;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using 畜牧业审核程序国产.Models.ToolsClass;

namespace 畜牧业审核程序国产.Models
{
    class OverRecordFunc
    {
        public static  FuncOutCome OverRecord(string oldPath, string NewPath)
        {
            FuncOutCome overRecordOutcome = new FuncOutCome();
            try { 
            Stopwatch sw = Stopwatch.StartNew();
            sw.Start();
            ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
            using (var packageOld = new ExcelPackage(new System.IO.FileInfo(oldPath)))
            using (var packageNew = new ExcelPackage(new FileInfo(NewPath)))
            {
                var wbOld = packageOld.Workbook;
                var wbNew = packageNew.Workbook;
                foreach (var shtOld in wbOld.Worksheets.Where(new Func<ExcelWorksheet, bool>(ws => Regex.IsMatch(ws.Name, "审核结果"))))//where 接收一个返回布尔值的委托
                {
                    string beDealingShtName = shtOld.Name;
                    var shtNew = wbNew.Worksheets.FirstOrDefault(sht => sht.Name.Equals(beDealingShtName));
                    if (shtNew == null)//新表找不到这个名字怎么办
                    {
                        overRecordOutcome.FuncOutComeInfoArgs += $"在新的审核结果中找不到{beDealingShtName}表,该表未过录";
                        continue;
                    }
                    var arrObj_oldValues = shtOld.Cells[shtOld.Dimension.Address].Value;
                    var arrObj_newValues = shtNew.Cells[shtNew.Dimension.Address].Value;
                    int oldAllRowCounts = shtOld.Dimension.End.Row;
                    int oldAllColumnCounts = shtOld.Dimension.End.Column;
                    int newAllRowCounts = shtNew.Dimension.End.Row;
                    int newAllColumnCounts = shtNew.Dimension.End.Column;
                    if (oldAllRowCounts == 1)
                    {
                        continue;
                    }
                    for (int i = 2; i <= oldAllRowCounts; i++)//先在第一列(审核说明)一行一行从第二行开始往下寻找有写过说明的单元格
                    {

                        if (shtOld.Cells[i, 1].Value == null)//如果审核说明列没有说明,就下一条
                        {
                            continue;
                        }
                        //找到了写过审核说明的行
                        string strVerify = shtOld.Cells[i, 1].Value.ToString();
                        string strOldRowUnion = string.Join("", shtOld.Cells[i, 2, i, oldAllColumnCounts].Select(colum => colum.Value?.ToString() ?? ""));//获取到本行从第二列开始到最后一列的字符串合并连接,如果单元格为空,用空字符串代替
                        //Cells[i, 2, i, oldAllColumnCounts]：是一个范围选择器，表示从第 i 行的第 2 列到第 i 行的第 oldAllColumnCounts 列之间的所有单元格。

                        // Select：这是一个 LINQ 扩展方法，用于对集合中的每个元素进行转换操作。
                        //colum => colum.Value?.ToString() ?? ""：这是一个 Lambda 表达式，用于转换每个单元格的值：
                        //colum.Value：表示当前单元格的值。
                        //?.ToString()：表示如果 colum.Value 不为 null，则调用 ToString() 方法将其转换为字符串；如果为 null，则跳过转换。
                        //?? ""：表示如果 colum.Value 为 null，则使用空字符串 "" 代替。
                        string formulateOfVerifyInOld = null;
                        for (int k = i - 1; k > 1; k--)//从当前行开始往上倒,找到公式名称说明
                        {
                            //下面这段没意义了
                            if (shtOld.Cells[k, 2].Value == null)
                            {
                               // overRecordOutcome.FuncOutComeInfoArgs += $"旧审核结果{shtOld.Name}表的B{k}单元格为空,该养殖户如果有审核说明,将不会被过录";
                                continue;
                            }
                            if (shtOld.Cells[k, 2].Value.ToString().Contains("说明"))
                            {
                                formulateOfVerifyInOld = shtOld.Cells[k, 2].Value.ToString();
                                break;
                            }
                        }
                        //去新的审核结果里查找有没有同一条审核公式
                        bool isFindTheSameFormulaInNew = false;
                        for (int j = 2; j <= newAllRowCounts; j++)//新表在第二列(审核公式说明所在列)从第二行开始往下找
                        {
                            if (shtNew.Cells[j, 2].Value == null)//为空就跳过(有些地方的县,乡会为空)
                            {
                                continue;
                            }
                            if (shtNew.Cells[j, 2].Value.ToString().Equals(formulateOfVerifyInOld))//如果在新表里面找到了这个审核公式
                            {
                                isFindTheSameFormulaInNew = true;
                                int rowOfTheSameFormulaInNew = j;
                                bool isInNewFindTheSameFormulaSNextFormula = false;//找到这个审核公式的区间范围(通过找到它下一条审核公式的头(类型)所在的行,跟本条审核公式所在的行中间,就是错误养殖户的范围)
                                int rowOfNextFormula = 0;
                                for (int m = j + 1; m < newAllRowCounts; m++)
                                {
                                    if (shtNew.Cells[m, 2].Value == null)
                                    { continue; }
                                    if (shtNew.Cells[m, 2].Value.ToString().Contains("类型"))
                                    {
                                        rowOfNextFormula = m; break;

                                    }
                                }
                                if (!isInNewFindTheSameFormulaSNextFormula)//如果找不到本条审核公式的下一条,那么本条审核公式是本表所有审核公式的最后一条,因此错误养殖户的范围是总行数+1
                                {
                                    rowOfNextFormula = newAllRowCounts + 1;
                                }
                                for (int n = rowOfTheSameFormulaInNew + 1; n < rowOfNextFormula; n++)
                                {
                                    try
                                    {
                                        string strNewRowUnion = string.Join("", shtNew.Cells[n, 2, n, newAllRowCounts].Select(column => column.Value?.ToString() ?? ""));//在此区间内,新表的每一行的字符串全部联合起来
                                        //通过与旧表的字符串联合进行比对,如果比对上,把审核说明复制过来

                                        if (strOldRowUnion.Equals(strNewRowUnion))
                                        {
                                            shtNew.Cells[n, 1].Clear();
                                            shtNew.Cells[n, 1].Value = strVerify;
                                            break;
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        overRecordOutcome.FuncSuccessCode = FuncOutComeCodeType.Error;
                                        overRecordOutcome.FuncOutComeInfoArgs += ex.Message;
                                        overRecordOutcome.Icon = Icon.Error;
                                        StaticLogger.SystemError($"出现错误,错误信息{ex.Message},{Environment.NewLine}堆栈为{ex.StackTrace},{Environment.NewLine}对象为{ex.Source},{Environment.NewLine}方法为{ex.TargetSite}");
                                        return overRecordOutcome;
                                    }
                                }
                            }
                        }
                    }
                }
                File.WriteAllBytes(NewPath, packageNew.GetAsByteArray());
            }
            sw.Stop();
            long time = sw.ElapsedMilliseconds;
            overRecordOutcome.FuncSuccessCode = FuncOutComeCodeType.Success;
            //if (overRecordOutcome.FuncOutComeInfoArgs != null)
            //{
            //    overRecordOutcome.Icon = Icon.Info;
            //    overRecordOutcome.SomeOtherInfo = "过录成功,但是旧表里某些行第二列单元格为空,导致该行的审核说明没有过录,请查看!";
            //   // this.TextSchedule = overRecordOutcome.FuncOutComeInfoArgs;
            //}
            //else
            //{
            //    overRecordOutcome.Icon = Icon.Success;
            //    overRecordOutcome.SomeOtherInfo = "过录成功,所有行都已经过录";
            //}
            //await MyMessagebox.ShowAsyncInMainWindow(overRecordOutcome.SomeOtherInfo, overRecordOutcome.Icon);


            if (overRecordOutcome.FuncOutComeInfoArgs != null)
            {
                overRecordOutcome.Icon = Icon.Info;
                overRecordOutcome.SomeOtherInfo = "过录成功,但是旧表里某些行第二列单元格为空,导致该行的审核说明没有过录,请查看!";
                // this.TextSchedule = overRecordOutcome.FuncOutComeInfoArgs;
            }
            else
            {
                overRecordOutcome.Icon = Icon.Success;
                overRecordOutcome.SomeOtherInfo = "过录成功,所有行都已经过录";
            }

            return overRecordOutcome;
            }
            catch (Exception ex)
            {
               
                StaticLogger.SystemError($"过录出错,错误信息为{ex.Message}");
                StaticLogger.SystemError($"堆栈为{ex.StackTrace},{Environment.NewLine}对象为{ex.Source},{Environment.NewLine}方法为{ex.TargetSite}");
                overRecordOutcome.Icon = Icon.Error;
                overRecordOutcome.FuncSuccessCode= FuncOutComeCodeType.Error;
                overRecordOutcome.FuncOutComeInfoArgs = $"出现错误,原因是{ex.Message}";
                return overRecordOutcome;
            }

        }

    }
}
